import ImgRate from '../../sql/module/factory/img_rate';
import Rate from '../../sql/module/factory/rate';
import Template from '../../sql/module/factory/template';
import User from '../../sql/module/user/user';
import { AddRate, RateValidator } from '../../validators/rate';
import { InfoValidator, ListValidator } from '../../validators/public';
import auth from '../../middlewares/auth';
import { Success, Forbbidend, Repeatedly, NotFound } from '../../code/http-exception';
import { sequelize } from '../../sql/db';
import { Op } from 'sequelize';
import RateEncrypt from '../../sql/module/_dictionaries/rateencrypt';
User.hasMany(Rate)
Rate.belongsTo(User)
Template.hasMany(Rate)
Rate.belongsTo(Template)
Rate.hasMany(ImgRate)
ImgRate.belongsTo(Rate)
Rate.hasMany(Rate)
Rate.belongsTo(Rate)
Rate.hasMany(RateEncrypt)
RateEncrypt.belongsTo(Rate)

const router: Api = new Map()

//添加评价
router.set('/addRate', [auth('public'), async (ctx, next) => {
    const v = await new AddRate().validate(ctx)
    const imgs = v.get('body.imgs')
    const TemplateId = v.get('query.id')
    let msg = v.get('body.message')
    const UserId = ctx.auth.id
    const needEncrypt = msg.match(/\$\(.*?\)/g)
    const Encrypt = needEncrypt?.map((item: string | any[], index: string) => {
        msg = msg.replace(item, '$(' + index + ')')
        return {
            key: '$(' + index + ')',
            value: item.slice(2, item.length - 1)
        }
    });
    const count = await Rate.count({ where: { TemplateId, UserId } })
    if (count) { throw new Repeatedly('评价已完成,请勿重复评价') }
    const rate = await Rate.create({
        message: msg,
        TemplateId,
        rate: v.get('body.rate'),
        RateId: v.get('body.RateId'),
        UserId
    })
    const id = rate?.dataValues.id
    if (imgs) {
        await ImgRate.bulkCreate(
            imgs.map((item: any) => ({
                url: item,
                RateId: id
            })))
    }
    if (Encrypt) {
        await RateEncrypt.bulkCreate(
            Encrypt.map((item: any) => ({
                RateId: id,
                ...item
            }))
        )
    }
    const mess = await Rate.findOne({
        attributes: { include: [[sequelize.literal('rate.UserId=' + UserId), 'isSelf']] },
        where: { id: rate.dataValues.id }, include: [ImgRate, {
            model: User,
            attributes: ['fullUrl', 'id', 'nickname', 'avatar']
        }]
    })
    throw new Success(mess)
}])
//删除评价
router.set('/delete', [auth('public'), async (ctx, next) => {
    const v = await new InfoValidator().validate(ctx)
    const id = v.get('query.id')
    const UserId = ctx.auth.id
    const message = await Rate.findOne({
        where: {
            TemplateId: id,
            UserId
        }
    })
    if (!message) { throw new NotFound() }
    await message.destroy()
    throw new Success()
}])
//获取个人评价
router.set('/getRate', [auth('public'), async (ctx, next) => {
    const v = await new InfoValidator().validate(ctx)
    const id = v.get('query.id')
    const UserId = ctx.auth.id
    const message = await Rate.findOne({
        where: {
            TemplateId: id,
            UserId
        },
        include: [Rate, ImgRate, RateEncrypt]
    })
    throw new Success(message)
}])

//对话消息列表
router.set('/message', [auth('public'), async (ctx, next) => {
    const v = await new RateValidator().validate(ctx)
    const UserId = ctx.auth.id
    const TemplateId = v.get('body.TemplateId')
    const RateId = v.get('body.RateId')
    const limit = v.get('query.limit')
    const page_index = v.get('query.page_index')
    const where: any = {}
    if (RateId)
        where.RateId = RateId
    else {
        where.TemplateId = TemplateId
        where.RateId = null
    }
    const rows = await Rate.findAll({
        attributes: {
            include: [[
                sequelize.literal(`(
                SELECT COUNT(*)
                FROM rates
                WHERE
                    Rate.id = rates.RateId
            )`),
                'RateCount'
            ], [sequelize.literal('rates.UserId=' + UserId), 'isSelf']]
        },
        where,
        include: [ImgRate, {
            model: User,
            attributes: ['fullUrl', 'id', 'nickname', 'avatar']
        }],
        limit: limit * 1,
        offset: (page_index - 1) * limit,
        order: [[sequelize.literal('RateCount'), 'DESC'], ['id', 'DESC']]
    })
    await Rate.update({
        readed: true
    }, {
        where: { AtUserId: UserId, ...where }
    })
    const count = await Rate.count({ where })
    throw new Success({ list: rows, total: count })
}])

//获取模版全部评价
router.set('/messages', [auth('public'), async (ctx, next) => {
    const v = await new ListValidator().validate(ctx)
    const limit = v.get('query.limit')
    const page_index = v.get('query.page_index')
    const message = v.get('body.message')
    const TemplateId = v.get('body.TemplateId')
    if (!TemplateId) throw new Forbbidend('模版Id缺失')
    const search_key: any = { TemplateId }
    message && (search_key.message = {
        [Op.substring]: message
    })
    const { rows, count } = await Rate.findAndCountAll({
        attributes: {
            include: [[
                sequelize.literal(`(
            SELECT COUNT(*)
            FROM imgrates
            WHERE
                Rate.id = imgrates.RateId
            )`),
                'imgCount'
            ]]
        },
        where: search_key,
        include: [{ model: ImgRate }, {
            model: User,
            attributes: ['fullUrl', 'id', 'nickname', 'avatar']
        }, { model: Rate, attributes: ['message', 'createdAt', 'create'] }],
        distinct: true,
        limit: limit * 1,
        offset: (page_index - 1) * limit,
        order: [['id', 'DESC']]
    })
    throw new Success({ list: rows, total: count })
}])

//管理员获取模版全部评价
router.set('/messageList', [auth('comments'), async (ctx, next) => {
    const v = await new ListValidator().validate(ctx)
    const limit = v.get('query.limit')
    const page_index = v.get('query.page_index')
    const message = v.get('body.message')
    const TemplateId = v.get('body.TemplateId')
    if (!TemplateId) throw new Forbbidend('模版Id缺失')
    const search_key: any = { TemplateId }
    message && (search_key.message = {
        [Op.substring]: message
    })
    const { rows, count } = await Rate.findAndCountAll({
        where: search_key,
        include: [ImgRate, {
            model: User,
            attributes: ['fullUrl', 'id', 'nickname', 'avatar']
        }, RateEncrypt, Rate],
        distinct: true,
        limit: limit * 1,
        offset: (page_index - 1) * limit,
        order: [['id', 'DESC']]
    })
    throw new Success({ list: rows, total: count })
}])

//删除自己发送的消息
router.set('/delete', [auth('public'), async (ctx, next) => {
    const v = await new InfoValidator().validate(ctx)
    const UserId = ctx.auth.id
    const id = v.get('query.id')
    await Rate.destroy({
        where: {
            id,
            UserId
        }
    })
    throw new Success()
}])

//获取未读消息列表
// router.set('/notRead', [auth('public'), async (ctx, next) => {
//     const UserId = ctx.auth.id
//     const { rows, count } = await Rate.findAndCountAll({
//         attributes: { include: [[sequelize.literal('Notice.UserId=' + UserId), 'isArt']] },
//         where: {
//             readed: 0,
//             AtUserId: UserId
//         },
//         include: [{
//             model: User,
//             attributes: ['fullUrl', 'id', 'nickname', 'avatar']
//         }, { model: Notice, attributes: [] }],
//         distinct: true,
//         limit: 20
//     })
//     throw new Success({ list: rows, total: count })
// }])

// //全部已读
// router.set('/allRead', [auth('public'), async (ctx, next) => {
//     const userId = ctx.auth.id
//     await Rate.update({
//         readed: true
//     }, {
//         where: {
//             AtUserId: userId
//         }
//     })
//     throw new Success()
// }])

//管理员获取全部消息用于删除不合适的消息
// router.set('/messageList', [auth('messageList'), async (ctx, next) => {
//     const v = await new ListValidator().validate(ctx)
//     const limit = v.get('query.limit')
//     const page_index = v.get('query.page_index')
//     const message = v.get('body.message')
//     const userNickname = v.get('body.userNickname')
//     const blockWhere: any = {}
//     const AreaId = ctx.auth.AreaId
//     const search_key: any = {}
//     const user_search_key: any = {}
//     AreaId && (blockWhere.AreaId = AreaId)
//     message && (search_key.message = {
//         [Op.substring]: message
//     })
//     userNickname && (user_search_key.nickname = {
//         [Op.substring]: userNickname
//     })
//     const rows = await Rate.findAll({
//         attributes: { exclude: ['updatedAt'] },
//         where: search_key,
//         include: [ImgRate, {
//             model: User,
//             attributes: ['fullUrl', 'id', 'nickname', 'avatar'],
//             where: user_search_key
//         }],
//         limit: limit * 1,
//         offset: (page_index - 1) * limit,
//         order: [['id', 'DESC']]
//     })
//     const count = await Rate.count({
//         where: search_key,
//         include: [{ model: User, where: user_search_key }],
//     })
//     throw new Success({ list: rows, total: count })
// }])

//管理员删除消息
router.set('/deleteRate', [auth('deleteRate'), async (ctx, next) => {
    const v = await new InfoValidator().validate(ctx)
    const id = v.get('query.id')
    await Rate.destroy({
        where: {
            id
        }
    })
    throw new Success()
}])

//商家回复
router.set('/reply', [auth('comments'), async (ctx, next) => {
    const v = await new InfoValidator().validate(ctx)
    const RateId = v.get('query.id')
    const message = v.get('body.message')
    await Rate.create({ RateId, message })
    throw new Success()
}])

export { router }